package cn.stylefeng.guns.sys.modular.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.base.auth.context.LoginContextHolder;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.core.util.DateUtil;
import cn.stylefeng.guns.sys.core.util.ExcelFormatUtil;
import cn.stylefeng.guns.sys.core.util.ExcelUtil;
import cn.stylefeng.guns.sys.core.util.RedisUtils;
import cn.stylefeng.guns.sys.core.util.UUIDUtils;
import cn.stylefeng.guns.sys.modular.system.controller.BaseFrontController;
import cn.stylefeng.guns.sys.modular.system.entity.*;
import cn.stylefeng.guns.sys.modular.system.mapper.*;
import cn.stylefeng.guns.sys.modular.system.model.params.*;
import cn.stylefeng.guns.sys.modular.system.model.result.*;
import cn.stylefeng.guns.sys.modular.system.service.*;
import cn.stylefeng.roses.core.reqres.response.ErrorResponseData;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author modular/system
 * @since 2020-11-19
 */
@Service
public class ZxBxMingxiServiceImpl extends ServiceImpl<ZxBxMingxiMapper, ZxBxMingxi> implements ZxBxMingxiService {
    private static final Logger log = LoggerFactory.getLogger(ZxBxMingxiServiceImpl.class);
    @Resource
    private ZxBxService zxBxService;
    @Resource
    private ZxKemuMapper zxKemuMapper;
    @Resource
    private ZxBxMapper zxBxMapper;
    @Resource
    private ZxBxMingxiMapper zxBxMingxiMapper;

    @Resource
    private MdzxService mdzxService;
    @Resource
    private ZxKemuKeyMapper zxKemuKeyMapper;

    @Resource
    private ZxKemuKeyService zxKemuKeyService;

    @Resource
    private ZxHuopinService zxHuopinService;

    @Resource
    private ZxChengbenMingxiMapper zxChengbenMingxiMapper;

    @Resource
    private RedisUtils redisUtils;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData add(ZxBxMingxiParam param) {
        ZxKemu zxKemu = zxKemuMapper.selectById(param.getBtyZxKemuId());
        Set<String> jsSet = new HashSet<String>();
        jsSet.add("2");
        if (!jsSet.contains(zxKemu.getLevel())) {
            return new ErrorResponseData("只能选择二级科目！");
        }

        //保存单据
        ZxBxMingxi entity = getEntity(param);
        entity.setCreateUser(LoginContextHolder.getContext().getUserId());
        entity.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        this.save(entity);



        return new ErrorResponseData("保存成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData addNewItem(ZxBxMingxiParam param) {

        if(param.getStatus()!=null && param.getStatus().equals("2")){
            param.setStatus(null);
        }

        if(param.getJine()!=null && param.getJine().doubleValue()<0){
            param.setStatus("9");
        }

        //根据关键字id,查找二级科目id信息
        ZxKemuKey zxKemuKey = zxKemuKeyMapper.selectById(param.getKeywordId());
        param.setBtyZxKemuId(zxKemuKey.getBtyZxKemuId());
        param.setQtkm(zxKemuKey.getKeyword());
        param.setGongshi(param.getJine().toString());


        ZxKemu zxKemu = zxKemuMapper.selectById(param.getBtyZxKemuId());
        Set<String> jsSet = new HashSet<String>();
        jsSet.add("2");
        if (!jsSet.contains(zxKemu.getLevel())) {
            return new ErrorResponseData("关键字只能建在二级科目下！");
        }

        //保存单据
        ZxBxMingxi entity = getEntity(param);
        entity.setCreateUser(LoginContextHolder.getContext().getUserId());
        entity.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        this.save(entity);
        this.baseMapper.updateStatusNull();




        return new SuccessResponseData("保存成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData addNewItemGhs(ZxBxMingxiParam param) {
        ZxBxMingxi entity = getEntity(param);

        //保存主表
        ZxBx head = this.zxBxService.getEntity(param.getHead());
        head.setPinpai(param.getPinpai());
        if(param.getBtyZxChengbenId()==-1){
            head.setBtyZxChengbenId(null);
            this.zxBxMapper.insert(head);
            entity.setBtyZxChengbenId(head.getBtyZxChengbenId());
        }else {
            this.zxBxMapper.updateById(head);
        }

        //保存单据
        entity.setCreateUser(LoginContextHolder.getContext().getUserId());
        entity.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        //String hpid=param.getHuopinId();

        //设置科目
        ZxHuopin hp = zxHuopinService.getById(param.getHuopinId());
        ZxHuopinParam zxHuopinParam=new ZxHuopinParam();
        if(ToolUtil.isEmpty(hp)){
            List<ZxHuopinResult>list=zxHuopinService.findPageBySpec(zxHuopinParam).getData();
            for (ZxHuopinResult huopin:list) {
                entity.setBtyZxChengbenMingxiId(UUIDUtils.getId());
                entity.setBtyZxKemuId(huopin.getBtyZxKemuId());
                entity.setBtyZxChengbenId(head.getBtyZxChengbenId());
                if(ToolUtil.isNotEmpty(huopin.getDanjia())){
                    entity.setUnitPrice(new BigDecimal(huopin.getDanjia()));
                    entity.setJine(new BigDecimal(huopin.getDanjia()));
                }
                entity.setQtkm(huopin.getName());
                this.save(entity);
            }
        }else{
            entity.setBtyZxKemuId(hp.getBtyZxKemuId());
            entity.setBtyZxChengbenId(head.getBtyZxChengbenId());
            this.save(entity);
        }

        return new SuccessResponseData(entity);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData addNewItemGhss(ZxBxMingxiParam param) {
        ZxBxMingxi entity = getEntity(param);

        //保存主表
        ZxBx head = this.zxBxService.getEntity(param.getHead());
        head.setPinpai(param.getPinpai());
        if(param.getBtyZxChengbenId()==-1){
            head.setBtyZxChengbenId(null);
            head.setCreateUser(LoginContextHolder.getContext().getUserId());
            head.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
            this.zxBxMapper.insert(head);
            entity.setBtyZxChengbenId(head.getBtyZxChengbenId());
        }else {
            this.zxBxMapper.updateById(head);
        }

        //保存单据
        entity.setCreateUser(LoginContextHolder.getContext().getUserId());
        entity.setCreateUserName(LoginContextHolder.getContext().getUser().getName());

        String ids=param.getIds();
        String[] idss = ids.split(",");

        for (String id : idss) {
            //设置科目
            ZxHuopin hp = zxHuopinService.getById(id);
            entity.setBtyZxKemuId(hp.getBtyZxKemuId()==null?0L:hp.getBtyZxKemuId());
            entity.setBtyZxChengbenId(head.getBtyZxChengbenId());
            entity.setBtyZxChengbenMingxiId(UUIDUtils.getId());
            if(ToolUtil.isNotEmpty(hp.getDanjia())){
                entity.setUnitPrice(new BigDecimal(hp.getDanjia()));
                entity.setJine(new BigDecimal(hp.getDanjia()));
            }
            entity.setHuopinId(hp.getBtyZxHuopinId());
            entity.setQtkm(hp.getName());
            this.save(entity);
        }
        BigDecimal zongJia=zxBxMingxiMapper.calculateChengbenJine(head.getBtyZxChengbenId());
        entity.setZongjia(zongJia);
        return new SuccessResponseData(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(ZxBxMingxiParam param){
        boolean isDel = false;
        ZxBxMingxi zxChengbenMingxi = this.getById(param);
        if(zxChengbenMingxi.getStatus()==null){
            zxChengbenMingxi.setStatus("2");
        }
        isDel =  this.removeById(getKey(param));

        if(zxChengbenMingxi.getBtyZxChengbenId()!=null && !zxChengbenMingxi.getBtyZxChengbenId().equals("")){
            zxBxService.updateForMingxi(zxChengbenMingxi.getBtyZxChengbenId());
        }

        return isDel;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteGhs(ZxBxMingxiParam param){
        boolean isDel = false;
        ZxBxMingxi zxChengbenMingxi = this.getById(param);
        if(zxChengbenMingxi.getStatus()==null){
            zxChengbenMingxi.setStatus("2");
        }
        //只有待提交 待审批状态下可以删除，其他状态不能删除
        if(zxChengbenMingxi.getStatus().equals("4") || zxChengbenMingxi.getStatus().equals("3")|| zxChengbenMingxi.getStatus().equals("5")){
            isDel =  this.removeById(getKey(param));

            if(zxChengbenMingxi.getBtyZxChengbenId()!=null && !zxChengbenMingxi.getBtyZxChengbenId().equals("")){
                zxBxService.updateForMingxi(zxChengbenMingxi.getBtyZxChengbenId());
            }
        }
        return isDel;
    }

    /**
     * 修改逻辑
     * v1 先删除再增加
     * v2 直接修改
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ZxBxMingxiParam param){
        if(param.getJine()!=null && param.getJine().doubleValue()<0){
            param.setStatus("9");
        }

        //将原来的修改注释，拆分为先删除再添加
        //根据关键字id,查找二级科目id信息
        if(param.getKeywordId()!=null){
            ZxKemuKey zxKemuKey = zxKemuKeyMapper.selectById(param.getKeywordId());
            param.setBtyZxKemuId(zxKemuKey.getBtyZxKemuId());
            param.setQtkm(zxKemuKey.getKeyword());
            param.setGongshi(param.getJine().toString());
        }

        //由于张总桌面端只有status is null 才能打款，所以需要如果stauts是2时，将设置成null
        ZxBxMingxi m= getEntity(param);
        this.updateById(m);
        this.baseMapper.updateStatusNull();

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void shenheTijiao(ZxBxMingxiParam param) throws Exception{
        if(param.getBtyZxKemuId()==null || param.getBtyZxKemuId().equals("")){
            throw new Exception("请设置货品对应的科目或点击科目同步");
        }

        //将原来的修改注释，拆分为先删除再添加
        //根据关键字id,查找二级科目id信息

//        ZxHuopin hp = zxHuopinService.getById(param.getHuopinId());
//        param.setBtyZxKemuId(hp.getBtyZxKemuId());
//        param.setQtkm(hp.getName());
//        param.setGongshi(param.getJine().toString());

        //由于张总桌面端只有status is null 才能打款，所以需要如果stauts是2时，将设置成null
        ZxBxMingxi m= getEntity(param);
        this.updateById(m);

        //更新主表状态
        ZxBx cb = this.zxBxMapper.selectById(param.getBtyZxChengbenId());
        cb.setStatus(param.getStatus());
        this.zxBxMapper.updateById(cb);
    }

    @Override
    public ResponseData shenpiByDanhao(ZxBxMingxiParam param) {
        if(param.getBtyZxChengbenId()==null||param.getBtyZxChengbenId().equals("")){
            return  ResponseData.error("没有选择单号");
        }
        ZxBxMingxiParam np = new ZxBxMingxiParam();
        np.setBtyZxChengbenId(param.getBtyZxChengbenId());
        List<ZxChengbenMingxiResult> mingxiResultList = this.baseMapper.customList(np);
        boolean isDk = false;
        for (ZxChengbenMingxiResult mingxiResult : mingxiResultList) {
            if(mingxiResult.getStatus().equals("1")){
                isDk = true;
                break;
            }
        }
        if(isDk){
            return  ResponseData.error("已打款，不能批量审批");
        }

        if(param.getStatus().equals("2")){
            //审批通过
            for (ZxChengbenMingxiResult mingxiResult : mingxiResultList) {
                //更新记录，放入成本id
                ZxBxMingxi mingxisave = new ZxBxMingxi();
                ToolUtil.copyProperties(mingxiResult, mingxisave);
                mingxisave.setStatus("2");//3 待审批
                this.baseMapper.updateById(mingxisave);
                this.baseMapper.updateStatusNull();

            }
        }
        if(param.getStatus().equals("5")){
            //审批退回

            for (ZxChengbenMingxiResult mingxiResult : mingxiResultList) {
                //更新记录，放入成本id
                ZxBxMingxi mingxisave = new ZxBxMingxi();
                ToolUtil.copyProperties(mingxiResult, mingxisave);
                mingxisave.setStatus("5");//3 待审批
                this.baseMapper.updateById(mingxisave);
            }
        }
        //同步主表信息
        ZxBx model = this.zxBxMapper.selectById(param.getBtyZxChengbenId());
        model.setStatus(param.getStatus());
        this.zxBxMapper.updateById(model);
        return ResponseData.success();
    }

    public boolean updateStatusById(Long id) {
        ZxBxMingxi mx = Optional.ofNullable(this.baseMapper.selectById(id)).orElseThrow(RuntimeException::new);
        LambdaUpdateWrapper<ZxBxMingxi> updateWrapper = new LambdaUpdateWrapper<ZxBxMingxi>();
        updateWrapper.set(ZxBxMingxi::getStatus,null);
        updateWrapper.eq(ZxBxMingxi::getBtyZxChengbenMingxiId,mx.getBtyZxChengbenMingxiId());
        int i = this.baseMapper.update(mx, updateWrapper);
        return i==1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData update2(ZxBxMingxiParam param) {

        if(param.getStatus()!=null&&param.getStatus().trim().equals("1")){
            return new ErrorResponseData("该记录已经打款不可修改");
        }

        if(param.getBtyZxChengbenId()!=null&&param.getBtyZxChengbenId()>0){
            return new ErrorResponseData("该记录已经生成总单据不可修改");
        }
        //根据关键字id,查找二级科目id信息
        ZxKemuKey zxKemuKey = zxKemuKeyMapper.selectById(param.getKeywordId());
        param.setBtyZxKemuId(zxKemuKey.getBtyZxKemuId());
        param.setQtkm(zxKemuKey.getKeyword());
        param.setGongshi(param.getJine().toString());


        ZxBxMingxi oldEntity = getOldEntity(param);
        Long oldKeMuId = oldEntity.getBtyZxKemuId();
        Long newKeMuId = param.getBtyZxKemuId();
        Long newBtyZxMdzxId = param.getBtyZxMdzxId();

        //先删除再重新添加明细
        ZxBxMingxiParam deleteParam = new ZxBxMingxiParam();
        deleteParam.setBtyZxChengbenMingxiId(param.getBtyZxChengbenMingxiId());
        this.delete(deleteParam);
        ZxBxMingxiParam addParam = new ZxBxMingxiParam();
        addParam.setBtyZxChengbenId(oldEntity.getBtyZxChengbenId());
        addParam.setBtyZxMdzxId(newBtyZxMdzxId);
        addParam.setBtyZxKemuId(newKeMuId);
        addParam.setBtyZxKemuIdView(param.getBtyZxKemuIdView());
        addParam.setJine(param.getJine());
        addParam.setQtkm(param.getQtkm());
        addParam.setBeizhu(param.getBeizhu());
        addParam.setGongshi(param.getGongshi());
        addParam.setShuliang(param.getShuliang());
        addParam.setUnitPrice(param.getUnitPrice());
        addParam.setDaKuan(param.getDaKuan());
        addParam.setBtyyBxdaId(param.getBtyyBxdaId());
        addParam.setBtyyBxdaIdView(param.getBtyyBxdaIdView());
        addParam.setKeywordId(param.getKeywordId());
        addParam.setStatus(param.getStatus());
        this.add(addParam);

        //更新总单据1.修改前后门店一致 2.修改前后数据不一致
        //1.修改前后门店一致




        return SuccessResponseData.success();

    }

    @Override
    public ResponseData updateGhs(ZxBxMingxiParam param) {

        if(param.getStatus()!=null&&param.getStatus().trim().equals("1")){
            return new ErrorResponseData("该记录已经打款不可修改");
        }

        if(param.getStatus()!=null&&param.getStatus().trim().equals("2")){
            return new ErrorResponseData("该记录已审核待打款不可修改");
        }

        //根据关键字id,查找二级科目id信息
        this.updateById(getEntity(param));
        this.zxBxService.updateForMingxi(param.getBtyZxChengbenId());
        return SuccessResponseData.success();
    }

    private void updateChengBenJie(ZxBxMingxiParam param) {
        //更新成本对应的总金额
        BigDecimal sum = this.baseMapper.calculateChengbenJine(param.getBtyZxChengbenId());
        ZxChengbenParam zxChengbenParam = new ZxChengbenParam();
        zxChengbenParam.setBtyZxChengbenId(param.getBtyZxChengbenId());
        //获取门店id
        ZxBx chengben = zxBxService.getById(param.getBtyZxChengbenId());
        zxChengbenParam.setBtyZxMdzxId(chengben.getBtyZxMdzxId());
        zxChengbenParam.setZongjia(sum == null ? BigDecimal.ZERO : sum);
        zxBxService.update(zxChengbenParam);
    }


    @Override
    public ZxChengbenMingxiResult findBySpec(ZxBxMingxiParam param) {
        return null;
    }

    @Override
    public List<ZxChengbenMingxiResult> findListBySpec(ZxBxMingxiParam param) {
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(ZxBxMingxiParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public ResponseData obtainFromBaoxiaodan(ZxTzqkViewResult param) {


        return ResponseData.success();
    }

    @Override
    public List<ZxChengbenMingxiResult> selectAllMingXiUnderLevel(ZxBxMingxiParam param) {
        List<ZxChengbenMingxiResult> list = this.baseMapper.selectAllMingXiUnderLevel(param);
        return list;
    }

    @Override
    public List<ZxChengbenMingxiResult> selectAllMingXiAndKemuInfo() {
        return this.baseMapper.selectAllMingXiAndKemuInfo();
    }

    private Serializable getKey(ZxBxMingxiParam param) {
        return param.getBtyZxChengbenMingxiId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private ZxBxMingxi getOldEntity(ZxBxMingxiParam param) {
        return this.getById(getKey(param));
    }

    private ZxBxMingxi getEntity(ZxBxMingxiParam param) {
        ZxBxMingxi entity = new ZxBxMingxi();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }


    /**
     * 去除字符串中的指定字符串
     *
     * @param contentStr
     * @param target
     * @return
     */
    private String deleteTargetStr(String contentStr, String target) {
        String str = contentStr.replaceAll(",", "，");
        List<String> strList = Arrays.asList(str.split("，"));
        List arrList = new ArrayList(strList);
        Iterator<String> iter = arrList.iterator();
        while (iter.hasNext()) {
            String item = iter.next();
            if (item.equals(target)) {
                iter.remove();
                break;
            }
        }
        Object collect = arrList.stream().collect(Collectors.joining("，"));

        String resultStr = collect.toString();
//        if (arrList.size() > 0) {
//            resultStr = resultStr + "，";
//        }
        return resultStr;
    }

    public String addContent(String contentStr, String kemu, String jine) {
        if (contentStr == null || "".equals(contentStr)) {
            return kemu + jine;
        }

        String str = contentStr.replaceAll(",", "，");
        List<String> strList = Arrays.asList(str.split("，"));
        List arrList = new ArrayList(strList);
        Iterator<String> iter = arrList.iterator();

        List<String> arrList_n = new ArrayList<String>();
        boolean isHas = false;
        while (iter.hasNext()) {
            String item = iter.next();
            int kmIndx = item.indexOf(kemu);
            if (kmIndx > -1) {
//                String shuzi = item.substring(kmIndx+kemu.length());
//                System.out.println(shuzi);
                item += "+" + jine;
                isHas = true;
            }
            arrList_n.add(item);
        }
        Object collect = arrList_n.stream().collect(Collectors.joining("，"));
        String resultStr = collect.toString();
        if (!isHas) {
            resultStr = resultStr + "，" + kemu + jine;
        }
        return resultStr;
    }

    public String subContent(String contentStr, String kemu, String jine) {
        if (contentStr == null || "".equals(contentStr)) {
            return kemu + jine;
        }

        String str = contentStr.replaceAll(",", "，");
        List<String> strList = Arrays.asList(str.split("，"));
        List arrList = new ArrayList(strList);
        Iterator<String> iter = arrList.iterator();

        List<String> arrList_n = new ArrayList<String>();
        boolean isHas = false;
        while (iter.hasNext()) {
            String item = iter.next();
            int kmIndx = item.indexOf(kemu);
            String shuziNew = "";
            boolean isJian = false;
            if (kmIndx > -1) {
                String shuzi = item.substring(kmIndx + kemu.length());
                System.out.println(shuzi);
                String[] shuziArr = shuzi.split("\\+");
                for (String sz : shuziArr) {
                    System.out.println(sz);
                    if (!isJian && sz.equals(jine)) {
                        //有多个，只能去一个
                        isJian = true;
                    } else {
                        if ("".equals(shuziNew)) {
                            shuziNew = sz;
                        } else {
                            shuziNew += "+" + sz;
                        }
                    }
                }
                if (!"".equals(shuziNew)) {
                    arrList_n.add(kemu + shuziNew);
                }
            } else {
                arrList_n.add(item);
            }
        }
        Object collect = arrList_n.stream().collect(Collectors.joining("，"));
        String resultStr = collect.toString();
        return resultStr;
    }


    @Override
    public ResponseData btnImportMdbx(MultipartFile file, Long btyZxChengbenId) throws IOException {
        String fname = file.getName();
        Workbook wb = ExcelUtil.getWorkBook(file);
        //获取所有的门店装修的门店信息
        MdzxParam mdzxParam = new MdzxParam();
        mdzxParam.setContainsCopy("no");
        List<MdzxResult> mdzxResultList = mdzxService.customList(mdzxParam);
        Map<String, Long> mdzxMap = mdzxResultList.stream().collect(Collectors.toMap(MdzxResult::getBtyBrandIdView, MdzxResult::getBtyZxMdzxId));

        //获取所有的二级科目-全
        List<ZxTzqkViewResult> zxKemuResultList2 = zxKemuMapper.selectAllErjiKemu("2");
        Map<String, Long> erjiKeMuMap = zxKemuResultList2.stream().collect(Collectors.toMap(ZxTzqkViewResult::getName, ZxTzqkViewResult::getSecondLevelId));
        List<ZxBxMingxiParam> mxList = new ArrayList<ZxBxMingxiParam>();

        Sheet sheet = wb.getSheetAt(0);
        int lastRowNum = sheet.getLastRowNum();

        for (int i = 1; i <= lastRowNum; i++) {
            Row row = sheet.getRow(i);
            if (row == null) {
                continue;
            }
            Cell dmcell = row.getCell(2);
            Cell km2cell = row.getCell(3);
            Cell zycell = row.getCell(4);
            Cell jecell = row.getCell(5);
            if (ToolUtil.isOneEmpty(dmcell, zycell, km2cell, jecell)) {
                return new ErrorResponseData("第" + (i + 1) + "行数据不全，请完善后再试");
            }
            String dm = dmcell.getStringCellValue().trim();
            String zy = zycell.getStringCellValue().trim();
            String km2 = km2cell.getStringCellValue().trim();
            String gs = jecell.toString();
            Object v = ExcelUtil.getCellFormatValue(jecell);
            if (ToolUtil.isOneEmpty(dm, zy, km2, v)) {
                return new ErrorResponseData("第" + (i + 1) + "行数据不全，请完善后再试");
            }
            if (mdzxMap.get(dm) == null) {
                return new ErrorResponseData("第" + (i + 1) + "行未找到门店信息（" + dm + "），请先添加装修门店信息");
            }
            Long kemu2 = erjiKeMuMap.get(km2);
            if (kemu2 == null) {
                return new ErrorResponseData("第" + (i + 1) + "行,二级科目 ’" + km2 + "‘ 不存在，请完善科目后再试");
            }


            BigDecimal jine = new BigDecimal(v.toString());
            ZxBxMingxiParam mx = new ZxBxMingxiParam();
            mx.setBtyZxMdzxId(mdzxMap.get(dm));
            mx.setBtyZxKemuId(kemu2);
            mx.setBtyZxChengbenId(btyZxChengbenId);
            mx.setQtkm(zy);
            mx.setJine(jine);
//            mx.setGongshi(gs);
            mx.setCreateTime(new Date());
            mx.setCreateUser(LoginContextHolder.getContext().getUserId());
            mx.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
            mxList.add(mx);
        }
        for (ZxBxMingxiParam mx : mxList) {
            this.add(mx);
        }
        return SuccessResponseData.success();
    }



    /**
     *
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData createDakuandan(ZxBxMingxiParam param) {

        ZxKemuKeyParam zxKemuKeyParam = new ZxKemuKeyParam();
        List<ZxKemuKeyResult> zxKemuKeyResultList = zxKemuKeyMapper.customList(zxKemuKeyParam);
        Map<Integer, List<ZxKemuKeyResult>> zxKemuKeyResultMap = zxKemuKeyResultList.stream().collect(Collectors.groupingBy(ZxKemuKeyResult::getId));

        //根据门店和报销人分组
        //获取该店所有的报销单
        ZxBxMingxiParam ZxBxMingxiParam = new ZxBxMingxiParam();
        ZxBxMingxiParam.setBtyZxMdzxId(param.getBtyZxMdzxId());
        //0:未生成打款单 1：已生成打款单
        ZxBxMingxiParam.setCreateDakuanDan(0);
        List<ZxChengbenMingxiResult> chengbenMingxiResultList = this.baseMapper.customList(ZxBxMingxiParam);
        //按报销人分组-银行卡号
        Map<String, List<ZxChengbenMingxiResult>> bxdaMap = chengbenMingxiResultList.stream().collect(Collectors.groupingBy(ZxChengbenMingxiResult::getBtyyBxdaId));

        if (CollectionUtil.isNotEmpty(chengbenMingxiResultList)) {
            //根据银行卡

            for (Map.Entry<String, List<ZxChengbenMingxiResult>> thisMap : bxdaMap.entrySet()) {

                List<ZxChengbenMingxiResult> mingxiResultList = thisMap.getValue();


                ZxBx zxChengben = new ZxBx();

                zxChengben.setBtyZxMdzxId(param.getBtyZxMdzxId());
                //银行卡号
                zxChengben.setBtyyBxdaId(thisMap.getKey());
                BigDecimal zongjia = BigDecimal.ZERO;

                //摘要
                String zhaiyao = "";
                for (ZxChengbenMingxiResult mingxiResult : mingxiResultList) {
                    zongjia = zongjia.add(mingxiResult.getJine()).setScale(4, BigDecimal.ROUND_HALF_UP);

                    zhaiyao = zhaiyao + zxKemuKeyResultMap.get(mingxiResult.getKeywordId()).get(0).getKeyword() + mingxiResult.getJine() + ",";
                }
                zxChengben.setBtyyBxdaIdView(mingxiResultList.get(0).getBtyyBxdaIdView());
                zxChengben.setZongjia(zongjia);
                //日期
                zxChengben.setRiqi(new Date());
                zxChengben.setZhaiyao(zhaiyao);
                zxChengben.setYhKahao(thisMap.getKey());
                //生成打款单的默认是打款的
                zxChengben.setDaKuan("1");
                zxChengben.setLeixing("1");

                zxChengben.setCreateUser(LoginContextHolder.getContext().getUserId());
                zxChengben.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                zxBxMapper.insert(zxChengben);

                Long btyZxChengbenId = zxChengben.getBtyZxChengbenId();

                if (btyZxChengbenId != null && btyZxChengbenId > 0) {
                    for (ZxChengbenMingxiResult mingxiResult : thisMap.getValue()) {
                        mingxiResult.setBtyZxChengbenId(btyZxChengbenId);
                        //更新记录，放入成本id
                        ZxBxMingxi mingxisave = new ZxBxMingxi();
                        ToolUtil.copyProperties(mingxiResult, mingxisave);
                        this.baseMapper.updateById(mingxisave);
                    }
                }
            }
        } else {
            return new ErrorResponseData("没有要生成打款单的数据");
        }


        return ResponseData.success();
    }

    /**
     *  提交报销单
     * @param param
     * @return
     * by zwf 20210116
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData tijiaobaoxiaoGhs(ZxBxMingxiParam param) {
        Long btyZxChengbenId = param.getBtyZxChengbenId();

        param.setBtyZxChengbenId(btyZxChengbenId);
        List<ZxChengbenMingxiResult> mingxiResultList = this.baseMapper.customList(param);
        BigDecimal zongjia = new BigDecimal("0.00");
        for (ZxChengbenMingxiResult mingxiResult : mingxiResultList) {
            if(mingxiResult.getBtyZxKemuId()==null){
                return new ErrorResponseData("提交失败，货品["+mingxiResult.getQtkm()+"]未设置科目，请联系管理员！");
            }
            //更新记录，放入成本id
            ZxBxMingxi mingxisave = new ZxBxMingxi();
            ToolUtil.copyProperties(mingxiResult, mingxisave);
            mingxisave.setStatus("3");//3 待审批
            zongjia=zongjia.add(mingxiResult.getJine()==null?BigDecimal.ZERO:mingxiResult.getJine());
            this.baseMapper.updateById(mingxisave);
        }

        //获取当前成本ID
        ZxBx zxChengben = this.zxBxMapper.selectById(btyZxChengbenId);


        //生成单据号
        if(zxChengben.getCompany()==null || zxChengben.getCompany().equals("")){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String danhao = sdf.format(new Date());
            Long xlh = redisUtils.incr(danhao);
            zxChengben.setCompany("ZX"+danhao+String.format("%03d", xlh));
        }
        zxChengben.setZongjia(zongjia);
        zxChengben.setStatus("3");
        zxBxMapper.updateById(zxChengben);

        //合并货品分类，生成装修报销明细
        //先删除
        Map<String,Object> delMap =new HashMap<String,Object>();
        if(zxChengben.getCompany()!=null && !zxChengben.getCompany().equals("")){
            delMap.put("src_type",zxChengben.getCompany());
            delMap.put("create_user",LoginContextHolder.getContext().getUserId());
            zxChengbenMingxiMapper.deleteByMap(delMap);
        }


        //再新增
        List<ZxChengbenMingxiResult> list = zxBxMingxiMapper.mergeDetail(btyZxChengbenId);
        for (ZxChengbenMingxiResult zxChengbenMingxiResult : list) {
            ZxChengbenMingxi mingxi = new ZxChengbenMingxi();
            ToolUtil.copyProperties(zxChengbenMingxiResult, mingxi);
            mingxi.setCreateUser(LoginContextHolder.getContext().getUserId());
            mingxi.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
            mingxi.setStatus("3");
            mingxi.setPinpai(param.getPinpai());
            mingxi.setBxjine(zxChengbenMingxiResult.getJine());
            mingxi.setCreateTime(new Date());
            mingxi.setVoucherDate(DateUtil.getNowDate());
            zxChengbenMingxiMapper.insert(mingxi);
        }
        return ResponseData.success();
    }
/**
     *  提交报销单（被打回）
     * @param param
     * @return
     * by zwf 20210116
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData tijiaobaoxiaoGhsTh(ZxBxMingxiParam param) {
        //获取当前用户要提交的报销单
        param.setStatus("5");
        param.setCreateUser(LoginContextHolder.getContext().getUserId());

        List<ZxChengbenMingxiResult> mingxiResultList = this.baseMapper.customList(param);
        for (ZxChengbenMingxiResult mingxiResult : mingxiResultList) {
            //更新记录，放入成本id
            ZxBxMingxi mingxisave = new ZxBxMingxi();
            ToolUtil.copyProperties(mingxiResult, mingxisave);
            mingxisave.setStatus("3");//3 待审批
            this.baseMapper.updateById(mingxisave);
        }
        return ResponseData.success();
    }



    @Override
    public ResponseData queryCreateUser() {
        Map<String,Object> data = new HashMap<String,Object>();
        List<SelectResult> dataList = this.getBaseMapper().queryCreateUser();
        boolean isHasDqyh = false;
        String value = String.valueOf(LoginContextHolder.getContext().getUserId());
        String name = LoginContextHolder.getContext().getUser().getName();

        for(SelectResult s:dataList){
            if(s.getValue().equals(value)){
                isHasDqyh = true;
                break;
            }
        }

        if(!isHasDqyh){
            SelectResult c = new SelectResult();
            c.setLabel(name);
            c.setValue(value);
            dataList.add(c);
        }
        data.put("list",dataList);
        data.put("userid",LoginContextHolder.getContext().getUserId());
       return ResponseData.success(data);
    }

    @Override
    public void updateKemuByHuopinId(String btyZxHuopinId, String status) {
        this.baseMapper.updateKemuByHuopinId(btyZxHuopinId,status);
    }

    @Override
    public ResponseData kemuTongbu(ZxBxMingxiParam ZxBxMingxiParam) {
        //根据关键字同步货品科目
        System.out.println("获取未设置科目的货品");
        ZxHuopinParam hpPara = new ZxHuopinParam();
        List<ZxHuopinResult> list = zxHuopinService.findListBySpec(hpPara);
        for(ZxHuopinResult hp:list){
            if(hp.getBtyZxKemuId()!=null){
                continue;
            }
            String mingcheng = hp.getName();
            System.out.println("货品="+mingcheng);
            //根据名称获取科目
            ZxKemuKeyResult r =zxKemuKeyService.findByKeywords(mingcheng);
            if(r!=null){
                Long kmuid = r.getBtyZxKemuId();
                hp.setBtyZxKemuId(kmuid);
                zxHuopinService.update(getHuopinParamVo(hp));
                System.out.println("kmid="+kmuid);
            }
        }
        //同步没有科目的报销单
        this.updateKemuByHuopin();
        return ResponseData.success();
    }

    @Override
    public boolean choudian(ZxBxMingxiParam ZxBxMingxiParam) {
        ZxBxMingxi mx = this.baseMapper.selectById(ZxBxMingxiParam.getBtyZxChengbenMingxiId());
        BigDecimal je = mx.getJine();
        BigDecimal cdxs = new BigDecimal("0.05");
        BigDecimal cd = je.multiply(cdxs);
        mx.setCompanyView(cd.toString());
        this.baseMapper.updateById(mx);

        return true;
    }

    @Override
    public boolean buchoudian(ZxBxMingxiParam ZxBxMingxiParam) {
        ZxBxMingxi mx = this.baseMapper.selectById(ZxBxMingxiParam.getBtyZxChengbenMingxiId());
        mx.setCompanyView("0.00");

        this.baseMapper.updateById(mx);
        return true;
    }

    @Override
    public void updateStatusNull() {
        this.baseMapper.updateStatusNull();
    }

    private void updateKemuByHuopin() {
        this.baseMapper.updateKemuByHuopin();
    }

    private ZxHuopinParam getHuopinParamVo(ZxHuopinResult param) {
        ZxHuopinParam entity = new ZxHuopinParam();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }
    public static void main(String[] args) {
        ZxBxMingxiServiceImpl service = new ZxBxMingxiServiceImpl();
        String content = "装修管理费2000.00，租金5000.00+23000.00+2000.00，物业管理费6000.00";
        String km = "装修管理费";
        String jine = "2000.002";
        String contengt = service.subContent(content, km, jine);
        System.out.println(contengt);
    }

    @Override
    public void updateBySpec(ZxBxMingxiParam param){
        baseMapper.updateBySpec(param);
    }

    @Override
    public ResponseEntity<byte[]> exportMx(HttpServletRequest request, HttpServletResponse response, ZxBxMingxiParam param){
        try {
            Mdzx mdzx = mdzxService.getById(param.getBtyZxMdzxId());
            String fileName=(mdzx!=null?mdzx.getBtyBrandIdView()+"-装修明细":"装修明细");
            //获取明细列表
            List<Map<String, Object>> mingxiList = this.baseMapper.listMingxiDetail(param);
            InputStream stream = exportHandler(mingxiList, fileName);
            return new BaseFrontController().buildResponseEntity(stream,fileName+ ".xls");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出明细异常：{}",e.getMessage());
        }
        return null;
    }

    @Override
    public void tongbuKemu(String huopin_id) {
        this.getBaseMapper().tongbuKemu(huopin_id);
    }

    @Override
    public String queryBxqk(Long userId, Long btyZxMdzxId, String huopinId) {
        String r = "";
        List<ZxBxMingxiParam> list =this.getBaseMapper().queryBxqk(userId,btyZxMdzxId,huopinId);
        for(ZxBxMingxiParam mx:list){
            String danhao = mx.getCompany();
            String dm =mx.getCompanyView();
            BigDecimal je =mx.getJine();
            String str = "货品["+mx.getQtkm()+"] 在单号["+danhao+"]门店["+dm+"]中已报销，金额["+je+"]";
            if(r.equals("")){
                r= str;
            }else {
                r+=","+str;
            }
        }
        return r;
    }

    private InputStream exportHandler(List<Map<String, Object>> mingxiList ,String name){
        log.info("exportHandler start...");

        ByteArrayOutputStream out=null;
        InputStream is=null;

        // 保留1000条数据在内存中
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet();
        //报表样式
        CellStyle contentStyle = ExcelFormatUtil.contentStyle(wb);

        //设置第一行标题：指定 4 个参数，起始行，结束行，起始列，结束列,
        int firstRow = 1;
        int lastRow = 1;
        int firstCol = 1;
        int lastCol = 9;

        SXSSFRow row1 = sheet.createRow(0);
        row1.setHeight((short)600);
        SXSSFCell cell0 = row1.createCell(0);
        sheet.addMergedRegion(new CellRangeAddress(0,0,0,lastCol-1));
        cell0.setCellValue(name);
        cell0.setCellStyle(ExcelFormatUtil.titleSytle(wb));

        //设置内容标题
        int contentTitleStartRow = 2;
        String[] titles=new String[]{"序号","类别","名称","规格型号","单位","数量","单价(元)","金额(元)","报销金额(元)"};
        // 字段名所在表格的宽度，数量应与列字段名数量一致
        int[] withs = new int[]{2500, 5000, 5000, 5000, 5000, 5200, 5000, 5000, 5000};
        // 设置报表头样式,cell样式
        CellStyle headSytle = ExcelFormatUtil.headSytle(wb);
        ExcelFormatUtil.initContentTitleEX(sheet,headSytle,contentTitleStartRow,titles,withs);


        int contentStartRow = 3;

        for(int i=0;i<mingxiList.size();i++){
            Map<String, Object> mx=mingxiList.get(i);
            SXSSFRow row = sheet.createRow(contentStartRow+i-1);
            int j=0;
            SXSSFCell xh = row.createCell(j++);//xuhao
            xh.setCellStyle(contentStyle);
            xh.setCellValue(i+1);

            SXSSFCell cell = row.createCell(j++);//类别
            cell.setCellValue(mx.get("fenleiName")!=null?mx.get("fenleiName").toString():"");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//名称
            cell.setCellValue(mx.get("hpName")!=null?mx.get("hpName").toString():"");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//规格型号
            cell.setCellValue(mx.get("guige")!=null?mx.get("guige").toString():"");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//单位
            cell.setCellValue(mx.get("danwei")!=null?mx.get("danwei").toString():"");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//数量
            cell.setCellValue(mx.get("shuliang")!=null?mx.get("shuliang").toString():"");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//单价
            cell.setCellValue(mx.get("danjia")!=null?mx.get("danjia").toString():"");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//金额
            cell.setCellValue(mx.get("jine")!=null?mx.get("jine").toString():"");
            cell.setCellStyle(contentStyle);

            cell = row.createCell(j++);//报销金额
            cell.setCellValue(mx.get("bxjine")!=null?mx.get("bxjine").toString():"");
            cell.setCellStyle(contentStyle);

        }

        try {
            out = new ByteArrayOutputStream();
            wb.write(out);
            is=new ByteArrayInputStream(out.toByteArray());
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null){
                    out.close();
                }
                if(is!=null){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.info("exportHandler end...");
        return is;
    }


}
